package cn.u313.comm.utils;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class TeaUtil {
    private static final int[] KEY = new int[]{2023721096, -158607964, -2120859654, 1167034504};

    public TeaUtil() {
    }

    public static byte[] encrypt(byte[] content, int offset, int[] key, int times) {
        int[] tempInt = byteToInt(content, offset);
        int y = tempInt[0];
        int z = tempInt[1];
        int sum = 0;
        int delta = -1640531527;
        int a = key[0];
        int b = key[1];
        int c = key[2];
        int d = key[3];

        for(int i = 0; i < times; ++i) {
            sum += delta;
            y += (z << 4) + a ^ z + sum ^ (z >> 5) + b;
            z += (y << 4) + c ^ y + sum ^ (y >> 5) + d;
        }

        tempInt[0] = y;
        tempInt[1] = z;
        return intToByte(tempInt, 0);
    }

    public static byte[] decrypt(byte[] encryptContent, int offset, int[] key, int times) {
        int[] tempInt = byteToInt(encryptContent, offset);
        int y = tempInt[0];
        int z = tempInt[1];
        int delta = -1640531527;
        int a = key[0];
        int b = key[1];
        int c = key[2];
        int d = key[3];
        int sum;
        if (times == 32) {
            sum = -957401312;
        } else if (times == 16) {
            sum = -478700656;
        } else {
            sum = delta * times;
        }

        for(int i = 0; i < times; ++i) {
            z -= (y << 4) + c ^ y + sum ^ (y >> 5) + d;
            y -= (z << 4) + a ^ z + sum ^ (z >> 5) + b;
            sum -= delta;
        }

        tempInt[0] = y;
        tempInt[1] = z;
        return intToByte(tempInt, 0);
    }

    private static int[] byteToInt(byte[] content, int offset) {
        int[] result = new int[content.length >> 2];
        int i = 0;

        for(int j = offset; j < content.length; j += 4) {
            result[i] = transform(content[j + 3]) | transform(content[j + 2]) << 8 | transform(content[j + 1]) << 16 | content[j] << 24;
            ++i;
        }

        return result;
    }

    private static byte[] intToByte(int[] content, int offset) {
        byte[] result = new byte[content.length << 2];
        int i = 0;

        for(int j = offset; j < result.length; j += 4) {
            result[j + 3] = (byte)(content[i] & 255);
            result[j + 2] = (byte)(content[i] >> 8 & 255);
            result[j + 1] = (byte)(content[i] >> 16 & 255);
            result[j] = (byte)(content[i] >> 24 & 255);
            ++i;
        }

        return result;
    }

    private static int transform(byte temp) {
        int tempInt = temp;
        if (temp < 0) {
            tempInt = temp + 256;
        }

        return tempInt;
    }

    public static byte[] encryptByTea(String info) {
        byte[] temp = info.getBytes();
        int n = 8 - temp.length % 8;
        byte[] encryptStr = new byte[temp.length + n];
        encryptStr[0] = (byte)n;
        System.arraycopy(temp, 0, encryptStr, n, temp.length);
        byte[] result = new byte[encryptStr.length];

        for(int offset = 0; offset < result.length; offset += 8) {
            byte[] tempEncrpt = encrypt(encryptStr, offset, KEY, 32);
            System.arraycopy(tempEncrpt, 0, result, offset, 8);
        }

        return result;
    }

    public static String decryptByTea(byte[] secretInfo) {
        byte[] decryptStr = null;
        byte[] tempDecrypt = new byte[secretInfo.length];

        for(int offset = 0; offset < secretInfo.length; offset += 8) {
            decryptStr = decrypt(secretInfo, offset, KEY, 32);
            System.arraycopy(decryptStr, 0, tempDecrypt, offset, 8);
        }

        int n = tempDecrypt[0];
        return new String(tempDecrypt, n, decryptStr.length - n);
    }

    public static String e(String str) {
        System.err.println(str+">>>加密前");
        byte[] encryptInfo = encryptByTea(str);
        return Base64.getEncoder().encodeToString(encryptInfo);
    }

    public static String d(String str) {
        byte[] by = Base64.getDecoder().decode(str);
        return decryptByTea(by);
    }

    public static void main(String[] args) {
        String info = "你猜我手機上康客服號" + Math.random();
        String e=e(info);
        String d=d("l/DxjkNzVvY8H6SwkUfiiFkkF1sClLqVyN7/vFqMiHY=");
        System.out.println(e);
        System.out.println(d);
//        long time = System.currentTimeMillis();
//        byte[] encryptInfo = encryptByTea(info);
//        long time1 = System.currentTimeMillis();
//        byte[] var10 = encryptInfo;
//        int var9 = encryptInfo.length;
//
//        for(int var8 = 0; var8 < var9; ++var8) {
//            byte b = var10[var8];
//            System.err.println((char)b);
//        }
//
//        System.err.println("size:>>>" + encryptInfo.length);
//        System.out.println(Base64.getEncoder().encodeToString(encryptInfo));
//        byte[] by = Base64.getDecoder().decode(Base64.getEncoder().encodeToString(encryptInfo));
//        String decryptInfo = decryptByTea(by);
//        long time2 = System.currentTimeMillis();
//        System.out.println(decryptInfo);
//        System.err.println("解密耗時：" + (time2 - time));
    }
}
